﻿using Microsoft.SharePoint;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.UI.HtmlControls;
using System.Xml;

namespace Dunite.InfoRoad
{
    public class InfoRoadFile
    {
        public const string formUri = "http://www.dunite.se/inforoadfile/";

        string _currentView;
        public string CurrentView
        {
            get 
            {
                if (string.IsNullOrEmpty(_currentView))
                {
                    InfoRoadFormView view = this.infoRoadForm.Views.Where(v => v.@default == true).First();
                    _currentView = view.name;
                }
                return _currentView; 
            }
            set 
            { 
                _currentView = value;
                this.AddContext();
                this.SetJson();
            }
        }

        string _filename;
        public string Filename
        {
            get { return _filename; }
            set { _filename = value; }
        }

        public InfoRoadForm infoRoadForm
        {
            get;
            set;
        }

        public SPWeb web
        {
            get;
            set;
        }

        XmlDocument _form;
        public XmlDocument Form
        {
            get { return _form; }
            set { _form = value; }
        }

        string _json;
        public string Json
        {
            get { return _json; }
            set { _json = value; }
        }

        public InfoRoadFile()
        {
            this.web = SPContext.Current.Web;
        }
        public InfoRoadFile(SPWeb web)
        {
            this.web = web;
        }
        /// <summary>
        /// Sets FormTemplate
        /// Sets form xml file from SampleData
        /// Sets Json
        /// </summary>
        /// <param name="templatePath"></param>
        public void Create(string templatePath)
        {
            // http://dev11/sites/test/Beslut/Forms/InfoRoadForm/Template.mt
            string webRelativeFileUrl = templatePath.Substring(this.web.ServerRelativeUrl.Length + 1);
            SPFile formDataFile = web.GetFile(webRelativeFileUrl);
            this.SetXml(formDataFile);
            this.SetFormTemplate(this.FormTemplateFolder);
            this.AddContext();
            this.SetJson();
            this.Filename = string.Empty;
        }
        private XmlElement AddOrUpdateElement(string elementName, string textValue, XmlElement atElement)
        {
            //XmlNamespaceManager ns = new XmlNamespaceManager(this.Form.NameTable);
            var elements = atElement.GetElementsByTagName(elementName);
            XmlElement element = null;

            if (elements.Count == 0)
            {
                element = this.Form.CreateElement(elementName);
                XmlNode acceptNoneValid = atElement.AppendChild(element);
            }
            else
            {
                element = (XmlElement)elements[0];
            }
            if (!string.IsNullOrEmpty(textValue))
            {
                element.InnerText = textValue;
            }
            atElement.AppendChild(element);
            return element;
        }
        
        private void AddContext()
        {   
            XmlElement root = this.Form.DocumentElement;
            XmlNamespaceManager ns = new XmlNamespaceManager(this.Form.NameTable);
            var acceptNoneValids = root.GetElementsByTagName("InfoRoad.Context");
            XmlElement contextElement = this.AddOrUpdateElement("InfoRoad.Context",null,root);

            XmlElement currentViewElement = this.AddOrUpdateElement("CurrentView", null, contextElement);
            var currentView = this.GetView(this.CurrentView);

            currentViewElement.SetAttribute("Name",currentView.name);
            currentViewElement.SetAttribute("Accept", currentView.accept);

            //this.infoRoadForm.FormData.FormFilter
            //this.infoRoadForm.FormData.IncludeOnAllView
            XmlElement datasource = this.AddOrUpdateElement("DataSource", null, contextElement);
            XmlElement tidpunkt = this.AddOrUpdateElement("TidpunktFörVigsel", null, datasource);
            
            //foreach (var view in this.infoRoadForm.Views)
            //{
            //    if (string.IsNullOrEmpty(view.accept))
            //        continue;

            //    var viewNode = contextElement.GetElementsByTagName(view.name);
            //    if (viewNode != null)
            //        continue;

            //    XmlElement viewElement = this.AddOrUpdateElement(view.name, view.accept, contextElement);
            //}
        }

        public InfoRoadFormView GetView(string viewName)
        {
            InfoRoadFormView view = null;

            if (string.IsNullOrEmpty(viewName))
            {
                view = this.infoRoadForm.Views.Where(v => v.@default == true).First();
            }
            else
            {
                view = this.infoRoadForm.Views.Where(v => v.name == viewName).First();
            }
            // http://formtemplates/FaultReport/FaulReport.js
            //string viewModelUrl = this.web.Url + "/Forms/" + this.FormTemplateFolder + "/" + currentView.viewmodel;
            return view;
        }


        private void SetJson()
        {
            this.Json = Newtonsoft.Json.JsonConvert.SerializeXmlNode(this.Form);
        }

        private void SetXml(SPFile formFile)
        {
            this.Form = new XmlDocument();
            this.Form.Load(formFile.OpenBinaryStream());
        }

        public string FormTemplateFolder
        {
            get
            {
                return this.Form.DocumentElement.GetAttribute("formtemplate", this.Form.NamespaceURI);
            }
        }

        
        /// <summary>
        /// Sets form xml file from filename
        /// Sets form template
        /// </summary>
        /// <param name="fileName"></param>
        public void Read(string fileName)
        {
            //  /sites/test/Beslut/Form1.mt
            string webRelativeFileUrl =  fileName.Substring(this.web.ServerRelativeUrl.Length + 1);
            this.Filename = webRelativeFileUrl;
            // Load form and create json
            SPFile formFile = this.web.GetFile(this.Filename);
            this.SetXml(formFile);
            // Load formTemplate
            this.SetFormTemplate(this.FormTemplateFolder);
            
            this.AddContext();
            this.SetJson();

            
        }
        public void SaveNew(string saveLocation)
        {
            MemoryStream ms = new MemoryStream();
            this.Form.Save(ms);
            byte[] bytes = ms.ToArray();

            string webRelativeFileUrl = saveLocation.Substring(this.web.ServerRelativeUrl.Length + 1);
            this.Filename = webRelativeFileUrl + "/" + Path.GetRandomFileName() + ".mt";

            SPFile newFile = this.web.Files.Add(this.Filename, bytes);
            SPListItem item = newFile.Item;
            item["ContentType"] = "InfoRoadForm";
            item.Update();
            // Set ContentType and others...

        }
        public void Update()
        {
            MemoryStream ms = new MemoryStream();
            this.Form.Save(ms);
            byte[] bytes = ms.ToArray();

            
            
            SPFile formFile = this.web.GetFile( this.Filename);
            formFile.SaveBinary(bytes);
            

        }

        public void Delete()
        {
            this.web.Files.Delete( this.Filename);
        }

        private void SetFormTemplate(string formTemplateFolder)
        {
            SPFile formTemplateFile = this.web.GetFile("Forms/" + formTemplateFolder + "/Main.xml");
            System.Xml.Serialization.XmlSerializer infoRoadFormSerializer = new System.Xml.Serialization.XmlSerializer(typeof(InfoRoadForm));
            this.infoRoadForm = (InfoRoadForm)infoRoadFormSerializer.Deserialize(formTemplateFile.OpenBinaryStream());
        }

        internal void ReadJson(string JSON, string filename)
        {
            this.Json = JSON;
            this.Filename = filename;
            //string line = "Kalle";
            //int index = JSON.IndexOf(",\"__ko_mapping__\"");
            //string noKO = line.Substring(0, index) + "}";
            this.Form = Newtonsoft.Json.JsonConvert.DeserializeXmlNode(JSON);
            this.SetFormTemplate(this.FormTemplateFolder);
        }
    }
}
